/*************************************************
 * Copyright (C), 2009-2020, Kong.
 * File name: xml.c
 * Author: Kong       Version: 1.0       Date: 2009.2.26
 * Description:		解析xml格式配置文件
 * Others:
 * Function List:  // 主要函数列表，每条记录应包括函数名及功能简要说明
 * History:
*************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <fcntl.h>

#include "global.h"
#include "err_.h"

/**
 * get_env_info:
 * 从配置文件读取参数到数组
 *************************************************
 * filename	: 配置文件名
 * env		: 保存参数的二位数组
 * 返回值	：成功： 0
 *       失败： -1
 */
int get_env_info(const char *filename, unsigned char **env)
{
    //DEBUGLOG(fprintf(LOG,"Entering Function GetConfigInfo...\n"));
#ifdef DEBUG
    //printf("entering function get_env_info...\n");
#endif

    xmlDocPtr doc;		// 文档树指针
    xmlNodePtr curNode;		// 节点指针
    xmlChar *szKey;		// 临时保存查询结果

    doc = xmlReadFile(filename, "utf-8", XML_PARSE_RECOVER);
    if (doc == NULL) {
	return -1;
    }

    curNode = xmlDocGetRootElement(doc);
    if (NULL == curNode) {	//空文当
	xmlFreeDoc(doc);
	return -1;
    }
    //判断根元素是否为"ENV_VARIABLE"
    if (xmlStrcmp(curNode->name, BAD_CAST "ENV_VARIABLE")) {
	err_msg("wrong type document, root node != ENV_VARIABLE");
	xmlFreeDoc(doc);
	return -1;
    }

    curNode = curNode->children;

    //xmlNodePtr propNodePtr = curNode;
    while (curNode != NULL) {
	//获取当前节点内容
	/*if (!xmlStrcmp(curNode->name, BAD_CAST("USER"))) {

	   szKey = xmlNodeGetContent(curNode);
	   env[USER_INDEX] = calloc(strlen(szKey), sizeof(unsigned char));
	   strncpy(env[USER_INDEX], szKey, strlen(szKey) * sizeof(unsigned char));
	   xmlFree(szKey);

	   curNode = curNode->next;
	   continue;
	   }    
	 */

	if (!xmlStrcmp(curNode->name, BAD_CAST("PROMPT"))) {
	    szKey = xmlNodeGetContent(curNode);
	    env[PROMPT_INDEX] =
		calloc(strlen((char *) szKey), sizeof(unsigned char));
	    strncpy((char *) env[PROMPT_INDEX], (char *) szKey,
		    strlen((char *) szKey) * sizeof(unsigned char));
	    xmlFree(szKey);

	    //curNode = curNode->next;
	    //continue;
	    break;
	}

	curNode = curNode->next;
    }

    //释放文档树
    xmlFreeDoc(doc);
    //清空树
    xmlCleanupParser();

#ifdef DEBUG
    //printf("get environment from %s:\tUSER: %s\t PROMPT: %s\n", 
    // filename, env[USER_INDEX], env[PROMPT_INDEX]);
#endif

    return 0;
}


int creat_config_file(const char *);

int save_env(const char *filename, unsigned char **env) {
    //DEBUGLOG(fprintf(LOG,"Entering Function GetConfigInfo...\n"));
#ifdef DEBUG
    //printf("entering function save_env...\n");
#endif

    xmlDocPtr doc;		// 文档树指针
    xmlNodePtr curNode;		// 节点指针
    xmlNodePtr root_node;	//根节点指针	

    //判断文件是否存在，不存在则创建;
    if (access(filename, F_OK) != 0) {
	creat_config_file(filename);
    }

    //doc = xmlReadFile(filename, "utf-8", XML_PARSE_RECOVER);
    doc = xmlReadFile(filename, NULL, XML_PARSE_RECOVER);
    if (doc == NULL) {
    	err_quit("setting config informaiton failed");
	return -1;
    }

    root_node = xmlDocGetRootElement(doc);
    if (NULL == root_node) {	//空文当
	xmlFreeDoc(doc);
	return -1;
    }
    //判断根元素是否为"ENV_VARIABLE"
    if (xmlStrcmp(root_node->name, BAD_CAST "ENV_VARIABLE")) {
	err_msg("wrong type document, root node != ENV_VARIABLE");
	xmlFreeDoc(doc);
	return -1;
    }

    curNode = root_node;
    curNode = curNode->children;

    //xmlNodePtr propNodePtr = curNode;
    while (curNode != NULL) {
	//获取当前节点内容
	if (!xmlStrcmp(curNode->name, BAD_CAST("PROMPT"))) {
	    //删除原节点
	    //创建、插入新节点
	    //printf("xmlNodeGetContent(curNode): %s\n", (char *)xmlNodeGetContent(curNode));
	    xmlNodeSetContentLen(curNode, env[PROMPT_INDEX], strlen((char*)env[PROMPT_INDEX]) + 1);
	    //curNode = curNode->next;
	    //continue;
	    #ifdef DEBUG
	    //printf("xmlNodeGetContent(curNode): %s\n", (char *)xmlNodeGetContent(curNode));
	    #endif
	    break;
	}

	curNode = curNode->next;
    }
    
    if (curNode == NULL) {
    	//节点不存在，在根节点中直接创建节点
    	xmlNewTextChild(root_node, NULL, BAD_CAST "PROMPT", BAD_CAST(env[PROMPT_INDEX]));
    }
    //存储xml文档
    int nRel = xmlSaveFile(filename,doc);
    if (nRel != -1)
    {
       //printf("%d bytes be writen to xml file\n", nRel);
    }
    
    //释放文档树
    xmlFreeDoc(doc);
    //清空树
    xmlCleanupParser();

#ifdef DEBUG
    //printf("get environment from %s:\tUSER: %s\t PROMPT: %s\n", 
    //	filename, env[USER_INDEX], env[PROMPT_INDEX]);
#endif


    return 0;
}


int creat_config_file(const char *filename)
{
    //定义文档和节点指针
    xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
    xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"ENV_VARIABLE");

    //设置根节点
    xmlDocSetRootElement(doc,root_node);

    //在根节点中直接创建节点
    //xmlNewTextChild(root_node, NULL, BAD_CAST "PROMPT", BAD_CAST "->");

    //存储xml文档
    int nRel = xmlSaveFile(filename,doc);
    if (nRel != -1)
    {
       //printf("%d bytes be writen to xml file\n", nRel);
    }

    //释放文档内节点动态申请的内存
    xmlFreeDoc(doc);

    return 0;
}
